package com.tevintao.marketingsystem.services;

import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import com.tevintao.marketingsystem.datebase.DeviceInfo;
import com.tevintao.marketingsystem.commen.CommenApplication;
import com.tevintao.marketingsystem.datebase.DeviceInfoDB;
import com.tevintao.marketingsystem.log.LogManager;
import com.tevintao.marketingsystem.shell.Shell;
import com.tevintao.marketingsystem.tool.PhoneTool;
import com.tevintao.marketingsystem.tool.SystemPathTool;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Random;


public class DeviceInfoManager {

    private static Random r = new Random();


    private static DeviceInfoManager ourInstance = new DeviceInfoManager();

    public static DeviceInfoManager getInstance() {
        return ourInstance;
    }

    private DeviceInfoManager() {
    }


    private int getCurrentType() {
        int currentType = PhoneTool.MOBILE_TYPE_ERROR;
        if (!SystemPathTool.exitFile(AccountManager.ACCOUNT_NET_TYPE_FILE_PATH)) {
            return PhoneTool.MOBILE_TYPE_ERROR;
        }
        String typeTag = SystemPathTool.getOutPutContent(AccountManager.ACCOUNT_NET_TYPE_FILE_PATH);
        if (null != typeTag) {
            if (typeTag.equals(String.valueOf(PhoneTool.CHINA_MOBILE))) {
                currentType = PhoneTool.CHINA_MOBILE;
            } else if (typeTag.equals(String.valueOf(PhoneTool.CHINA_UNICOM))) {
                currentType = PhoneTool.CHINA_UNICOM;
            } else if (typeTag.equals(String.valueOf(PhoneTool.CHINA_TELECOM))) {
                currentType = PhoneTool.CHINA_TELECOM;
            }
        }
        return currentType;
    }

    public String resetNet() {
        String writeNetFile = checkMobileNetAndWriteNetFile();
        if (AccountManager.SUCCESS_TAG.equals(writeNetFile)) {
            return writeNewDefaultDeviceInfo();
        } else {
            return writeNetFile;
        }
    }


    public boolean isSameNet() {
        int fileType = getCurrentType();
        int netType = PhoneTool.getMobileTypeInt(CommenApplication.getApplication());
        LogManager.getInstance().logInfo("fileType == " + fileType + " netType = " + netType);
        return fileType == netType;
    }

    public String checkMobileNetAndWriteNetFile() {
        boolean exitNetTypeFile = SystemPathTool.exitFile(AccountManager.ACCOUNT_NET_TYPE_FILE_PATH);
        if (exitNetTypeFile) {
            if (!isSameNet()) {
                String deleteTag = deleteAllDeviceInfo();
                if (!AccountManager.SUCCESS_TAG.equals(deleteTag)) {
                    return deleteTag;
                }
            } else {
                LogManager.getInstance().logInfo("属于同一个网络");
                return AccountManager.SUCCESS_TAG;
            }
        } else {
            String deleteTag = deleteAllDeviceInfo();
            if (!AccountManager.SUCCESS_TAG.equals(deleteTag)) {
                return deleteTag;
            }
        }
        int netType = PhoneTool.getMobileTypeInt(CommenApplication.getApplication());
        String writeNetType = "echo " + netType + " > " + AccountManager.ACCOUNT_NET_TYPE_FILE_PATH;
        if (SystemPathTool.noResultIsSuccess(writeNetType)) {
            LogManager.getInstance().logInfo("写入网络类型成功");
        } else {
            return "写入网络类型文件失败";
        }
        return AccountManager.SUCCESS_TAG;
    }


    /**
     * 先删除网络类型文件，在删除所有设备信息文件
     *
     * @return
     */
    public String deleteAllDeviceInfo() {
        String cmd = "ls " + AccountManager.ACCOUNT_DATA_CACHE_PATH;
        Shell.ShellCommand command = Shell.runAsRoot(cmd);
        for (String account : command.output) {
//            if (!account.equals("clean") && !account.equals("test")) {
            if (AccountManager.isAccountFile(account)) {
                String deviceInfoPath = AccountManager.ACCOUNT_DATA_CACHE_PATH + account + "/" + AccountManager.ACCOUNT_DEVICE_INFO_FILE_NAME;
                if (SystemPathTool.exitFile(deviceInfoPath)) {
                    boolean removed = SystemPathTool.remove(deviceInfoPath);
                    if (!removed) {
                        return "删除设备信息失败" + deviceInfoPath + " account =" + account;
                    }
                }

                String locationPath = AccountManager.ACCOUNT_DATA_CACHE_PATH + account + "/" + AccountManager.LOCATION_FILE_NAME;
                if (SystemPathTool.exitFile(locationPath)) {
                    boolean removed = SystemPathTool.remove(locationPath);
                    if (!removed) {
                        return "删除位置信息失败" + locationPath + " account =" + account;
                    }
                }

                LogManager.getInstance().logInfo("AccountManager deleteAllDeviceInfo " + account);
            }
        }

        if (SystemPathTool.exitFile(AccountManager.LOCAL_DEVICE_INFO)) {
            boolean deleteDefaultInfo = SystemPathTool.remove(AccountManager.LOCAL_DEVICE_INFO);
            if (!deleteDefaultInfo) {
                return "删除默认设备文件失败";
            }
        }

        boolean removeNetType = SystemPathTool.remove(AccountManager.ACCOUNT_NET_TYPE_FILE_PATH);
        if (!removeNetType) {
            return "删除网络类型文件失败";
        }
        return AccountManager.SUCCESS_TAG;
    }


    public String writeNewDefaultDeviceInfo() {
        if (!SystemPathTool.exitFile(AccountManager.LOCAL_DEVICE_INFO)) {
            String deviceInfo = DeviceInfoManager.getInstance().getDefaultDeviceInfo();
            if (!TextUtils.isEmpty(deviceInfo)) {
                LogManager.getInstance().logInfo("writeNewDefaultDeviceInfo deviceInfo = " + deviceInfo);
                String codeInfo = null;
                try {
                    codeInfo = URLEncoder.encode(deviceInfo, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                if (TextUtils.isEmpty(codeInfo)) {
                    LogManager.getInstance().logError("codeInfo URLEncoder is null ");
                    return "codeInfo URLEncoder is null ";
                }
                String writeLocalMac = "echo " + codeInfo + " > " + AccountManager.LOCAL_DEVICE_INFO;
                boolean writeAccount = SystemPathTool.noResultIsSuccess(writeLocalMac);
                if (!writeAccount) {
                    return "写入默认设备信息失败";
                }
            } else {
                return "获取默认设备信息失败";
            }
        } else {
            return "写入新的设备信息之前，发现老的默认设备信息仍然存在";
        }
        return AccountManager.SUCCESS_TAG;
    }

//    Android 6.0 = API Level 23
//    Android 5.1.1 = API Level 22
//    Android 5.0.1 = API Level 21
//    Android 4.4W (L) = API Level 20
//    Android 4.4.2 = API Level 19
//    Android 4.3 = API Level 18
//    Android 4.2-4.2.2 = API Level 17
//    Android 4.1-4.1.1 = API Level 16
//    Android 4.0.3-4.0.4 = API Level 15
//    Android 4.0-4.0.2 = API Level 14
//    Android 3.2 = API Level 13
//    Android 3.1.x = API Level 12
//    Android 3.0.x = API Level 11
//    Android 2.3.3+ = API Level 10

    private int getApiLevel(String version) {
        if (version.startsWith("6.0")) {
            return 23;
        } else if (version.startsWith("5.1.1")) {
            return 22;
        } else if (version.startsWith("5.0.1")) {
            return 21;
        } else if (version.startsWith("4.4.2")) {
            return 19;
        } else if (version.startsWith("4.4")) {
            return 20;
        } else if (version.startsWith("4.3")) {
            return 18;
        } else if (version.startsWith("4.2")) {
            return 17;
        } else if (version.startsWith("4.1")) {
            return 16;
        } else if (version.startsWith("4.0.3") || version.startsWith("4.0.4")) {
            return 15;
        } else if (version.startsWith("4.0")) {
            return 14;
        } else if (version.startsWith("3.2")) {
            return 13;
        } else if (version.startsWith("3.1")) {
            return 12;
        } else if (version.startsWith("3.0")) {
            return 11;
        } else if (version.startsWith("2.3")) {
            return 10;
        }
        return -1;
    }

//    IMEI由15位数字组成，每位数字仅使用0~9的数字，其组成为：
//
//            1、前6位数（TAC，Type Approval Code）是“型号核准号码”，一般代表机型。
//            2、接着的2位数（FAC，Final Assembly Code）是“最后装配号”，一般代表产地。
//            3、之后的6位数（SNR，Serial Number，出厂序号）是“串号”，一般代表生产顺序号。
//            4、最后1位数（SP）通常是“0”，为检验码，备用。


    public static String getRandomICCID(String iccid) {
        if (iccid.length() > 2) {
            int spitIndex = iccid.length() / 2;
            String pre = iccid.substring(0, spitIndex);
            String end = getRandomIntStr(iccid.length() - spitIndex);
            return pre + end;
        }
        return "";
    }

    public static String getRandomImsi(String imsi) {
        if (imsi.length() > 10) {
            String pre = imsi.substring(0, 10);
            String end = getRandomIntStr(imsi.length() - 10);
            return pre + end;
        }
        return "";
    }

    /**
     * 随机snr码
     *
     * @param imei
     * @return
     */
    public static String getRandomImei(String imei) {
        if (imei.length() > 8) {
            int randomLength = imei.length() - 8;
            String ss = imei.substring(0, 8) + getRandomIntStr(randomLength);
            return ss;
        }
        return imei;
    }

    private static String getRandomIntStr(int length) {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(random.nextInt(10));
        }
        return sb.toString();
    }

    /**
     * 信息来源一个是现有设备信息，一种是从服务器拉取下来的设备信息。
     *
     * @return
     */
    public String getDeviceInfo() {
        JSONObject deviceJson = new JSONObject();

        JSONObject defaultJson = null;
        if (SystemPathTool.exitFile(AccountManager.LOCAL_DEVICE_INFO)) {
            String json = SystemPathTool.getOutPutContent(AccountManager.LOCAL_DEVICE_INFO);
            if (TextUtils.isEmpty(json)) {
                return "默认设备信息文件不存在";
            }
            String decode = null;
            try {
                decode = URLDecoder.decode(json, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            if (TextUtils.isEmpty(decode)) {
                return "解码设备信息失败";
            }
            try {
                defaultJson = new JSONObject(decode);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        if (null == defaultJson) {
            return "解析默认设置文件失败";
        }

        DeviceInfo deviceInfo = DeviceInfoDB.getRandomDeviceInfo();
//        一，Build
        if (null == deviceInfo) {
            return "读取本地设备信息数据库失败，请检查ms文件夹下是否存在设备信息数据库文件";
        }
        try {
//        Build.ID=KTU84P 大写的字母加数字，5-8位 或者 使用手机型号信息device_name
            deviceJson.put("Build.ID", deviceInfo.getDevice_name());
//        Build.DISPLAY=TBE570711_9721_V050107 大写的字母加数字，5-8位 或者 使用手机型号信息device
            deviceJson.put("Build.DISPLAY", deviceInfo.getDevice());
//        Build.PRODUCT=msm8610 使用手机型号信息device_product
            deviceJson.put("Build.PRODUCT", deviceInfo.getDevice_product());
//        Build.DEVICE=msm8610 使用手机型号信息device_product
            deviceJson.put("Build.DEVICE", deviceInfo.getDevice_product());
//        Build.BOARD=MSM8610 使用手机型号信息device_product
            deviceJson.put("Build.BOARD", deviceInfo.getDevice_product());
//        Build.MANUFACTURER=K-Touch 使用手机型号信息device_manufacture
            deviceJson.put("Build.MANUFACTURER", deviceInfo.getDevice_manufacture());
//        Build.BRAND=qcom 使用手机型号信息device_brand
            deviceJson.put("Build.BRAND", deviceInfo.getDevice_brand());
//        Build.MODEL=K-Touch E8 使用手机型号信息device_name
            deviceJson.put("Build.MODEL", deviceInfo.getDevice_name());
//        Build.HARDWARE=qcom 使用手机型号信息device_brand
            deviceJson.put("Build.HARDWARE", deviceInfo.getDevice_brand());
//        Build.SERIAL=E8  使用手机型号信息device_product
            deviceJson.put("Build.SERIAL", deviceInfo.getDevice_product());

//        Build.VERSION.CODENAME=REL  直接试用REL
            deviceJson.put("Build.VERSION.CODENAME", "REL");
//        Build.VERSION.INCREMENTAL=TBE570711_9721_V050107 和Build.DISPLAY相同
            deviceJson.put("Build.VERSION.INCREMENTAL", deviceInfo.getDevice());

            deviceJson.put("Build.VERSION.RELEASE", deviceInfo.getOs_version());
            int versionCode = getApiLevel(deviceInfo.getOs_version());
//        Build.VERSION.SDK=19 使用手机型号信息os_version对应信息
            deviceJson.put("Build.VERSION.SDK", versionCode);
//        Build.VERSION.SDK_INT=19 使用手机型号信息os_version对应信息
            deviceJson.put("Build.VERSION.SDK_INT", versionCode);

        } catch (JSONException e) {
            e.printStackTrace();
            return "Build JSONException " + e.toString();
        }

//        二，wifi
        try {
            String defaultMac = defaultJson.getString("MAC");
            deviceJson.put("MAC", getRandomMac(defaultMac));
            deviceJson.put("BSSID", getRandomMac(defaultMac));
        } catch (JSONException e) {
            e.printStackTrace();
            return "wifi MAC JSONException " + e.toString();
        }

        try {
            deviceJson.put("SSID", deviceInfo.getDevice_name());
            deviceJson.put("IPInt", 0);
            deviceJson.put("InetAddress", "192.168.0.1");
        } catch (JSONException e) {
            e.printStackTrace();
            return "wifi SSID JSONException " + e.toString();
        }
//        三，Gsm

        try {
            //        mInfoMap.put("PhoneNumber", "18612450000");
            deviceJson.put("PhoneNumber", "");
            //        mInfoMap.put("getDeviceId", "getDeviceId"); IMEI = 使用手机型号信息imei ,在随机中间几位
            deviceJson.put("getDeviceId", getRandomImei(deviceInfo.getImei()));

            //        mInfoMap.put("getNetworkCountryIso", "getNetworkCountryIso");
            String getNetworkCountryIso = defaultJson.getString("getNetworkCountryIso");
            deviceJson.put("getNetworkCountryIso", getNetworkCountryIso);

            //        mInfoMap.put("getNetworkOperator", "getNetworkOperator");
            String getNetworkOperator = defaultJson.getString("getNetworkOperator");
            deviceJson.put("getNetworkOperator", getNetworkOperator);

            //        mInfoMap.put("getNetworkOperatorName", "getNetworkOperatorName");
            String getNetworkOperatorName = defaultJson.getString("getNetworkOperatorName");
            deviceJson.put("getNetworkOperatorName", getNetworkOperatorName);

            //        mInfoMap.put("getSimCountryIso", "getSimCountryIso");
            String getSimCountryIso = defaultJson.getString("getSimCountryIso");
            deviceJson.put("getSimCountryIso", getSimCountryIso);

            //        mInfoMap.put("getSimOperator", "getSimOperator");
            String getSimOperator = defaultJson.getString("getSimOperator");
            deviceJson.put("getSimOperator", getSimOperator);

            //        mInfoMap.put("getSimOperatorName", "getSimOperatorName");
            String getSimOperatorName = defaultJson.getString("getSimOperatorName");
            deviceJson.put("getSimOperatorName", getSimOperatorName);

            //        mInfoMap.put("getSimSerialNumber", "getSimSerialNumber"); ICCID 需要还一点东西
            String getSimSerialNumber = defaultJson.getString("getSimSerialNumber");
            if (TextUtils.isEmpty(getSimSerialNumber)) {
                return "默认信息里面ICCID为空";
            }
            deviceJson.put("getSimSerialNumber", getRandomICCID(getSimSerialNumber));

            //        mInfoMap.put("getSubscriberId", "getSubscriberId");  IMSI 也需要还一点东西
            String getSubscriberId = defaultJson.getString("getSubscriberId");
            if (TextUtils.isEmpty(getSubscriberId)) {
                return "默认信息里面IMSI为空";
            }
            deviceJson.put("getSubscriberId", getSubscriberId);
        } catch (JSONException e) {
            e.printStackTrace();
            return "GSM JSONException " + e.toString();
        }

//        四，蓝牙
        try {
            deviceJson.put("BT_NAME", deviceInfo.getDevice_name());
            deviceJson.put("BTMAC", getRandomMac());
        } catch (JSONException e) {
            e.printStackTrace();
            return "BT JSONException " + e.toString();
        }
//        五，settings id
        try {
            deviceJson.put("ANDROID_ID", Long.toHexString(r.nextLong()).toUpperCase());
        } catch (JSONException e) {
            e.printStackTrace();
            return "ANDROID_ID JSONException " + e.toString();
        }

//        六，ua
        try {
            deviceJson.put("UA", deviceInfo.getUa());
        } catch (JSONException e) {
            e.printStackTrace();
            return "UA JSONException " + e.toString();
        }
//        七 ,屏幕分辨率
        try {
            deviceJson.put("Screen.width", deviceInfo.getWidth());
            deviceJson.put("Screen.height", deviceInfo.getHeight());
            deviceJson.put("Screen.density", deviceInfo.getDevice_density());
        } catch (JSONException e) {
            e.printStackTrace();
            return "SCREEND DISPLAY  JSONException" + e.toString();
        }
        return deviceJson.toString();
    }

    public static String getRandomMac(String trueMac) {
        if (TextUtils.isEmpty(trueMac)) {
            return null;
        }
        String[] values = trueMac.split(":");
        if (values.length != 6) {
            return null;
        }
        int v1 = r.nextInt(256);
        values[3] = Integer.toHexString(0x100 | v1).substring(1);

        int v2 = r.nextInt(256);
        values[4] = Integer.toHexString(0x100 | v2).substring(1);

        int v3 = r.nextInt(256);
        values[5] = Integer.toHexString(0x100 | v3).substring(1);


        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < values.length; i++) {
            sb.append(values[i]);
            if (i != values.length - 1) {
                sb.append(":");
            }
        }
        return sb.toString();
    }

    public static String getRandomMac() {
        String v1 = Integer.toHexString(0x100 | r.nextInt(256)).substring(1);
        String v2 = Integer.toHexString(0x100 | r.nextInt(256)).substring(1);
        String v3 = Integer.toHexString(0x100 | r.nextInt(256)).substring(1);
        String v4 = Integer.toHexString(0x100 | r.nextInt(256)).substring(1);
        String v5 = Integer.toHexString(0x100 | r.nextInt(256)).substring(1);
        String v6 = Integer.toHexString(0x100 | r.nextInt(256)).substring(1);
        return v1 + ":" + v2 + ":" + v3 + ":" + v4 + ":" + v5 + ":" + v6;
    }

    public static int getNum(int start, int end) {
        return (int) (Math.random() * (end - start + 1) + start);
    }

    public static String[] mobilePre = "135,136,137,138,139,150,151,152,158,159".split(",");
    public static String[] unicomPre = "130,131,132,155,156,185,186".split(",");
    public static String[] telecomPre = "133,153,180,189".split(",");

    /**
     * 返回手机号码
     */
    private static String getTel(String[] telFirst) {
        int index = getNum(0, telFirst.length - 1);
        String first = telFirst[index];
        String second = String.valueOf(getNum(1, 888) + 10000).substring(1);
        String third = String.valueOf(getNum(1, 9100) + 10000).substring(1);
        return first + second + third;
    }


    private String geRandomPhone() {
        int netType = PhoneTool.getMobileTypeInt(CommenApplication.getApplication());
        if (0 < netType) {
            if (netType == PhoneTool.CHINA_MOBILE) {
                return getTel(mobilePre);
            } else if (netType == PhoneTool.CHINA_UNICOM) {
                return getTel(unicomPre);
            } else if (netType == PhoneTool.CHINA_TELECOM) {
                return getTel(telecomPre);
            }
        }
        return "";
    }

    /**
     * 生成默认的信息，主要用于生成除从数据库查询出来的设备信息，详见有道笔记
     */
    public String getDefaultDeviceInfo() {
        JSONObject deviceJson = new JSONObject();
        // 一，Build
        //全部都需要从数据库查询出来
        //二，wifi
        WifiManager wifi = (WifiManager) CommenApplication.getApplication().getSystemService(Context.WIFI_SERVICE);
        WifiInfo info = wifi.getConnectionInfo();
        String mac = info.getMacAddress();
        try {
            deviceJson.put("MAC", mac);
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
//        三，Gsm

        TelephonyManager telephonyManager = (TelephonyManager) CommenApplication.getApplication().getSystemService(Context.TELEPHONY_SERVICE);
        try {
            String phone = telephonyManager.getLine1Number();
            if (TextUtils.isEmpty(phone)) {
                phone = geRandomPhone();
            }
            deviceJson.put("PhoneNumber", phone);

            //getDeviceId IMEI 从设备信息里面生成

            String getNetworkCountryIso = telephonyManager.getNetworkCountryIso();
            deviceJson.put("getNetworkCountryIso", getNetworkCountryIso);

            String getNetworkOperator = telephonyManager.getNetworkOperator();
            deviceJson.put("getNetworkOperator", getNetworkOperator);

            String getNetworkOperatorName = telephonyManager.getNetworkOperatorName();

            deviceJson.put("getNetworkOperatorName", getNetworkOperatorName);

            String getSimCountryIso = telephonyManager.getSimCountryIso();
            deviceJson.put("getSimCountryIso", getSimCountryIso);

            String getSimOperator = telephonyManager.getSimOperator();
            deviceJson.put("getSimOperator", getSimOperator);

            String getSimOperatorName = telephonyManager.getSimOperatorName();
            deviceJson.put("getSimOperatorName", getSimOperatorName);

            //ICCID
            String getSimSerialNumber = telephonyManager.getSimSerialNumber();
            deviceJson.put("getSimSerialNumber", getSimSerialNumber);

            //IMSI
            String getSubscriberId = telephonyManager.getSubscriberId();
            deviceJson.put("getSubscriberId", getSubscriberId);
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
//        四，蓝牙

//        BT_NAME  使用手机型号信息device_name
//        BTMAC 随机mac
//        五，settings
//        ANDROID_ID  Long.toHexString(v).toUpperCase();
        return deviceJson.toString();
    }
}
